--[[
Copyright (c) 2006-2017 LOVE Development Team

This software is provided 'as-is', without any express or implied
warranty.  In no event will the authors be held liable for any damages
arising from the use of this software.

Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must not
   claim that you wrote the original software. If you use this software
   in a product, an acknowledgment in the product documentation would be
   appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
--]]

-- Make sure love exists.
local love = require("love")

function love.nogame()

	local originalWidth, originalHeight = 800, 600
	local scaleX, scaleY = 1, 1
	
	local timers, lists
	love.load = function()
		local width, height = love.graphics.getDimensions()
		scaleX, scaleY = width / originalWidth, height / originalHeight
		
		local major, minor, rev = 0, 6, 2 --string.match(love._version_string, "(%d)%.(%d)%.(%d)")
		if not major then major = 0 end
		if not minor then minor = 0 end
		if not rev then rev = 0 end
	
		love.graphics.setBackgroundColor(0x84/0xff, 0xca/0xff, 0xff/0xff)

		local names = {
			"wheel_0",
			"wheel_1",
			"wheel_2",
			"wheel_3",
			"wheel_4",
			"wheel_5",
			"wheel_6",
			"wheel_7",
			"wheel_8",
			"wheel_9",
			"belt_tooth",
			"belt_track",
			"turret_body",
			"turret_cannon",
			"star",
			"knoll01",
			"knoll02",
			"knoll03",
			"knoll04",
			"tree01",
			"bubble",
			"love",
		}

		local function load_image(file, name, flags)
			local decoded = love.data.decode("string", "base64", file)
			return love.graphics.newImage(love.filesystem.newFileData(decoded, name:gsub("_", ".")), flags)
		end

		local images = {}
		local resources = require"resources"

		for i,v in pairs(names) do
			images[v] = load_image(resources[v..'_png'], v..'.png')
		end

		local pools = {
			{
				images.knoll01,
				images.knoll02,
			},
			{
				images.knoll03,
				images.knoll04,
			},
		}

		local List = {}
		List.__index = List

		List.new = function(self)
			local o = {
				head = nil,
			}
			setmetatable(o, List)
			return o
		end

		List.update = function(self, dt)
			local n = self.head
			while n do
				n:update(dt)
				n = n.next
			end
		end

		List.draw = function(self)
			local n = self.head
			while n do
				n:draw()
				n = n.next
			end
		end

		local Node = {}
		Node.__index = Node

		Node.new = function(self, object)
			local o = {
				next = nil,
			}
			setmetatable(o, List)
			return o
		end

		Node.insert = function(self, list)
			local h = list.head
			list.head = self
			self.next = h
		end

		Node.remove = function(self)
			--parent.next = self.next
		end

		local Object = Node:new()
		Object.__index = Object
		setmetatable(Object, Node)

		Object.new = function(self)
			local o = {
				image = nil,
				x = 0,
				y = 0,
				dx = -400,
				dy = 0,
				scale = 1,
				r = 0,
				duration = 30,
				passed = 0,
				t = 0,
				alpha = 255
			}
			setmetatable(o, Object)
			return o
		end

		Object.update = function(self, dt)
			self.passed = self.passed + dt
			while self.passed > self.duration do
				self.passed = self.passed - self.duration
			end
			self.t = self.passed/self.duration
		end

		Object.draw = function(self)
			if self.image then
				local x = self.x + self.dx*self.t
				local y = self.y + self.dy*self.t
				local r = self.r*self.t
				love.graphics.setColor(1, 1, 1, self.alpha/255)
				love.graphics.draw(self.image, x, y, r, self.scale)
				love.graphics.setColor(1, 1, 1, 1)
			end
		end

		local Tree = Object:new()
		Tree.__index = Tree
		setmetatable(Tree, Object)

		Tree.new = function(self)
			local o = {}
			o.image = images.tree01
			o.x = 800 + math.random(0, 800)
			o.y = 300 + math.random(0, 40)
			o.xt = -200;
			o.dx = o.xt - o.x
			o.speed = 100
			o.duration = -o.dx/o.speed
			setmetatable(o, Tree)
			return o
		end

		local Star = Object:new()
		Star.__index = Star
		setmetatable(Star, Object)

		Star.new = function(self, speed, scale)
			local o = {}
			o.image = images.star
			o.x = 800 + math.random(0, 800)
			o.y = -200 + math.random(0, 300)
			o.xt = -50;
			o.dy = 400
			o.dx = o.xt - o.x
			o.speed = speed
			o.scale = scale
			o.duration = -o.dx/o.speed
			o.r = math.pi * 5
			o.alpha = 100 + math.random(155)
			setmetatable(o, Star)
			return o
		end

		local Knoll = Object:new()
		Knoll.__index = Knoll
		setmetatable(Knoll, Object)

		Knoll.new = function(self, pool, var, speed)
			local o = {}
			o.image = pools[pool][math.random(1, #pools[pool])]
			o.x = 800 + math.random(0, 800)
			o.y = 300 + var - math.random(0, var*2)
			o.xt = -200;
			o.dx = o.xt - o.x
			o.speed = speed
			o.duration = -o.dx/o.speed
			setmetatable(o, Star)
			return o
		end

		local Belt = Object:new()
		Belt.__index = Belt
		setmetatable(Belt, Object)

		Belt.new = function(self, n)

			local o = {}

			o.r = 30
			o.d = o.r*2
			o.half_c = math.pi*o.r
			o.c = 2*o.half_c
			o.x = 200
			o.y = 300
			o.th = 1
			o.ta = 1
			o.w = o.th*o.half_c
			o.total = o.th*2+o.ta*2
			o.teeth = {}

			for i=0,n-1 do
				local b = { x = 0, y = 0, t = (o.total/n)*i }
				table.insert(o.teeth, b)
			end

			setmetatable(o, Belt)
			return o
		end

		Belt.update = function(self, dt)
			for i,b in ipairs(self.teeth) do
				b.t = b.t + dt

				if b.t < self.th then
					local t = b.t
					b.x = self.x + self.w * (t/self.th)
					b.y = self.y
				elseif b.t < self.th + self.ta then
					local t = (self.th + self.ta - b.t)
					b.x = self.x + self.w + math.cos(-math.pi*t + math.pi/2)*self.r
					b.y = self.y + self.r + math.sin(-math.pi*t + math.pi/2)*self.r
				elseif b.t < self.th*2 + self.ta then
					local t = (b.t - self.th*2 + self.ta)/self.th
					b.x = self.x + self.w * (2-t)
					b.y = self.y + self.d
				elseif b.t < self.total then
					local t = (self.th*2 + self.ta - b.t)
					b.x = self.x + math.cos(-math.pi*t + math.pi/2)*self.r
					b.y = self.y + self.r + math.sin(-math.pi*t + math.pi/2)*self.r
				else
					b.t = b.t - self.total
				end
			end
		end

		Belt.draw = function(self)
			for i,b in ipairs(self.teeth) do
				love.graphics.draw(images.belt_tooth, b.x, b.y)
			end
		end

		local Tank = Object:new()
		Tank.__index = Tank
		setmetatable(Tank, Object)

		Tank.new = function(self)
			local o = {}
			o.x = 200
			o.y = 490
			o.i = 49
			o.belt = Belt:new(30)
			o.belt.x = o.x-7
			o.belt.y = o.y-37
			o.angle = 0
			setmetatable(o, Tank)
			return o
		end

		Tank.update = function(self, dt)
			self.angle = self.angle + dt * math.pi/2
			self.belt:update(dt)
		end


		Tank.draw = function(self)
			love.graphics.draw(images.turret_cannon, self.x+30, self.y-80)
			love.graphics.draw(images.turret_body, self.x-12, self.y-110)
			love.graphics.draw(images.belt_track, self.belt.x-74, self.belt.y-28)		
			love.graphics.draw(images["wheel_"..tostring(major)], self.x, self.y, self.angle, 1, 1, 32, 32)
			love.graphics.draw(images["wheel_"..tostring(minor)], self.x+self.i, self.y, self.angle, 1, 1, 32, 32)
			love.graphics.draw(images["wheel_"..tostring(rev)], self.x+self.i*2, self.y, self.angle, 1, 1, 32, 32)
			self.belt:draw()
		end

		local Bubble = Object:new()
		Bubble.__index = Bubble
		setmetatable(Bubble, Object)

		 Bubble.new = function(self)
			local o = {}
			o.x = 240
			o.y = 190
			o.angle = 0
			setmetatable(o, Bubble)
			return o
		end

		Bubble.update = function(self, dt)
			self.angle = self.angle + dt*5
		end

		Bubble.draw = function(self)
			local yv = math.sin(self.angle)*5
			love.graphics.draw(images.bubble, self.x, self.y+yv)
			love.graphics.draw(images.love, self.x+8, self.y+yv+95)
		end

		timers = {}

		local Timer = {}
		Timer.__index = Timer

		Timer.spawn = function(self, tick, f)
			local o = {
				passed = 0,
				tick = tick,
				f = f
			}
			setmetatable(o, Timer)
			table.insert(timers, o)
		end

		Timer.update = function(self, dt)
			self.passed = self.passed + dt
			while self.passed > self.tick do
				self.passed = self.passed - self.tick
				self.f()
			end
		end

		lists = {
			b = List:new(),
			f = List:new()
		}

		do
			local t = Bubble:new()
			t:insert(lists.f)
		end

		do
			local t = Tank:new()
			t:insert(lists.f)
		end

		for i=1,3 do
			local t = Tree:new(50, 300)
			t:insert(lists.b)
		end


		for i=1,2 do
			local t = Knoll:new(1, 50, 100)
			t:insert(lists.b)
		end

		for i=1,40 do
			local t = Star:new(100, 1)
			t:insert(lists.b)
		end

		for i=1,5 do
			local t = Knoll:new(2, 100, 50)
			t:insert(lists.b)
		end

		for i,v in pairs(lists) do
			v:update(10)
		end

	end



	love.update = function(dt)

		for i,v in ipairs(timers) do v:update(dt) end


		for i,v in pairs(lists) do
			v:update(dt)
		end

		love.timer.sleep(0.010)
	end


	love.draw = function()
		love.graphics.scale(scaleX, scaleY)
		
		lists.b:draw()

		-- Ground
		love.graphics.setColor(146/255, 201/255, 87/255)
		love.graphics.rectangle("fill", 0, 530, 800, 70)
		love.graphics.setColor(205/255, 227/255, 161/255)
		love.graphics.rectangle("fill", 0, 520, 800, 10)
		love.graphics.setColor(1, 1, 1)

		lists.f:draw()

	end

	function love.resize(width, height)
		scaleX, scaleY = width / originalWidth, height / originalHeight
	end
	
	love.keypressed = function(key)
		if key == "escape" then
			love.event.quit()
		end
	end

	love.conf = function(t)
		t.title = "*Tank* you for using L\195\150VE 0.6.2 (Jiggly Juice)"
		t.gammacorrect = true
		t.modules.audio = false
		t.modules.sound = false
		t.modules.physics = false
		t.modules.joystick = false
		t.modules.font = false
		t.window.resizable = true
		t.window.highdpi = true

		if love._os == "iOS" then
			t.window.borderless = true
		end
	end

end

return love.nogame
